/*
 * Copyright (C) 2017 Jared Rummler
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jaredrummler.ohos.util;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;

/**
 *
 * <p>Example usage:</p>
 *
 * <pre>
 * <code>
 * HtmlBuilder html = new HtmlBuilder()
 * .p()
 * .b()
 * .font().color("red").face("sans-serif-condensed").text("Hello").close()
 * .close()
 * .close();
 *
 * // html.toString():
 * // &lt;p&gt;&lt;b&gt;&lt;font color=&quot;red&quot;
 * face=&quot;sans-serif-condensed&quot;&gt;Hello&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
 *
 * yourEditText.setText(html.toSpan());
 * </code>
 * </pre>
 *
 *
 * <ul>
 * <li><code>&lt;a href=&quot;...&quot;&gt;</code></li>
 * <li><code>&lt;b&gt;</code></li>
 * <li><code>&lt;big&gt;</code></li>
 * <li><code>&lt;blockquote&gt;</code></li>
 * <li><code>&lt;br&gt;</code></li>
 * <li><code>&lt;cite&gt;</code></li>
 * <li><code>&lt;dfn&gt;</code></li>
 * <li><code>&lt;div align=&quot;...&quot;&gt;</code></li>
 * <li><code>&lt;em&gt;</code></li>
 * <li><code>&lt;font color=&quot;...&quot; face=&quot;...&quot;&gt;</code></li>
 * <li><code>&lt;h1&gt;</code></li>
 * <li><code>&lt;h2&gt;</code></li>
 * <li><code>&lt;h3&gt;</code></li>
 * <li><code>&lt;h4&gt;</code></li>
 * <li><code>&lt;h5&gt;</code></li>
 * <li><code>&lt;h6&gt;</code></li>
 * <li><code>&lt;i&gt;</code></li>
 * <li><code>&lt;img src=&quot;...&quot;&gt;</code></li>
 * <li><code>&lt;p&gt;</code></li>
 * <li><code>&lt;small&gt;</code></li>
 * <li><code>&lt;strike&gt;</code></li>
 * <li><code>&lt;strong&gt;</code></li>
 * <li><code>&lt;sub&gt;</code></li>
 * <li><code>&lt;sup&gt;</code></li>
 * <li><code>&lt;tt&gt;</code></li>
 * <li><code>&lt;u&gt;</code></li>
 * <li><code>&lt;ul&gt;</code></li>
 * <li><code>&lt;li&gt;</code></li>
 * </ul>
 */
public class HtmlBuilder {
    private final StringBuilder html = new StringBuilder();

    private final LinkedList<String> tags = new LinkedList<>();

    /**
     * 构造
     *
     * @param element 字符串类型
     * @param data 数据值
     * @return HtmlBuilder
     */
    public HtmlBuilder open(String element, String data) {
        tags.add(element);
        html.append('<');
        html.append(element);
        if (data != null) {
            html.append(' ').append(data);
        }
        html.append('>');
        return this;
    }

    /**
     * 构造
     *
     * @param element 字符串类型
     * @return HtmlBuilder
     */
    public HtmlBuilder open(String element) {
        return open(element, null);
    }

    /**
    * 构造
    *
    * @param text 文本
    * @return HtmlBuilder
     */
    public HtmlBuilder style(String text) {
        html.append("<style>").append(text).append("</style>");
        return this;
    }

    /**
    * 构造
    *
    * @param element 字符串类型
    * @return HtmlBuilder
    */
    public HtmlBuilder close(String element) {
        html.append("</").append(element).append('>');
        for (Iterator<String> iterator = tags.iterator(); iterator.hasNext(); ) {
            if (iterator.next().equals(element)) {
                iterator.remove();
                break;
            }
        }
        return this;
    }

    /**
    * 构造
    *
    * @return 返回HtmlBuilder
    */
    public HtmlBuilder close() {
        if (tags.isEmpty()) {
            return this;
        }
        html.append("</").append(tags.removeLast()).append('>');
        return this;
    }

    /**
    * 构造
    *
    * @param element char类型
    * @return HtmlBuilder
     */
    public HtmlBuilder close(char element) {
        return close(String.valueOf(element));
    }

    /**
    * 构造
    *
    * @param isAppend 是否添加
    * @return HtmlBuilder
    **/
    public HtmlBuilder append(boolean isAppend) {
        html.append(isAppend);
        return this;
    }

    /**
    * 构造
    *
    * @param cr 添加char类型
    * @return HtmlBuilder
    */
    public HtmlBuilder append(char cr) {
        html.append(cr);
        return this;
    }

    /**
    * 构造
    *
    * @param id 添加int类型
    * @return HtmlBuilder
    */
    public HtmlBuilder append(int id) {
        html.append(id);
        return this;
    }

    /**
    * 构造
    *
    * @param ld 添加long类型
    * @return HtmlBuilder
    */
    public HtmlBuilder append(long ld) {
        html.append(ld);
        return this;
    }

    /**
     * 构造
     *
     * @param fd 添加float的类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(float fd) {
        html.append(fd);
        return this;
    }

    /**
     * 构造
     *
     * @param de 添加double类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(double de) {
        html.append(de);
        return this;
    }

    /**
     * 构造
     *
     * @param obj 添加object类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(Object obj) {
        html.append(obj);
        return this;
    }

    /**
     * 构造
     *
     * @param str 添加字符串类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(String str) {
        html.append(str);
        return this;
    }

    /**
     * 构造
     *
     * @param sb 添加stringBuffer类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(StringBuffer sb) {
        html.append(sb);
        return this;
    }

    /**
     * 构造
     *
     * @param chars 添加char[]数组
     * @return HtmlBuilder
     */
    public HtmlBuilder append(char[] chars) {
        html.append(chars);
        return this;
    }

    /**
     * 构造
     *
     * @param str char类型
     * @param offset int类型
     * @param len 长度
     * @return HtmlBuilder
     */
    public HtmlBuilder append(char[] str, int offset, int len) {
        html.append(str, offset, len);
        return this;
    }

    /**
     * 构造
     *
     * @param csq 添加charSequence类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(CharSequence csq) {
        html.append(csq);
        return this;
    }

    /**
     * 构造
     *
     * @param csq CharSequence类型
     * @param start 开始int类型
     * @param end 结束int类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(CharSequence csq, int start, int end) {
        html.append(csq, start, end);
        return this;
    }

    /**
     * 构造
     *
     * @param tag 添加tag类型
     * @return HtmlBuilder
     */
    public HtmlBuilder append(Tag tag) {
        html.append(tag.toString());
        return this;
    }

    /**
     * 构造
     *
     * @param href String类型
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder a(String href, String text) {
        return append(String.format(Locale.ROOT,"<a href=\"%s\">%s</a>", href, text));
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder b() {
        return open("b");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder b(String text) {
        html.append("<b>").append(text).append("</b>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder big() {
        return open("big");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder big(String text) {
        html.append("<big>").append(text).append("</big>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder blockquote() {
        return open("blockquote");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder blockquote(String text) {
        html.append("<blockquote>").append(text).append("</blockquote>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder br() {
        html.append("<br>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder cite() {
        return open("cite");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder cite(String text) {
        html.append("<cite>").append(text).append("</cite>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder dfn() {
        return open("dfn");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder dfn(String text) {
        html.append("<dfn>").append(text).append("</dfn>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder div() {
        return open("div");
    }

    /**
     * 构造
     *
     * @param align string类型
     * @return HtmlBuilder
     */
    public HtmlBuilder div(String align) {
        html.append(String.format(Locale.ROOT,"<div align=\"%s\">", align));
        tags.add("div");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder em() {
        return open("em");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder em(String text) {
        html.append("<em>").append(text).append("</em>");
        return this;
    }

    /**
     * 构造
     *
     * @return Font
     */
    public Font font() {
        return new Font(this);
    }

    /**
     * 构造
     *
     * @param color 颜色
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder font(int color, String text) {
        return font().color(color).text(text).close();
    }

    /**
     * 构造
     *
     * @param face 字符串
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder font(String face, String text) {
        return font().face(face).text(text).close();
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h1() {
        return open("h1");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h1(String text) {
        html.append("<h1>").append(text).append("</h1>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h2() {
        return open("h2");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h2(String text) {
        html.append("<h2>").append(text).append("</h2>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h3() {
        return open("h3");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h3(String text) {
        html.append("<h3>").append(text).append("</h3>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h4() {
        return open("h4");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h4(String text) {
        html.append("<h4>").append(text).append("</h4>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h5() {
        return open("h5");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h5(String text) {
        html.append("<h5>").append(text).append("</h5>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder h6() {
        return open("h6");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder h6(String text) {
        html.append("<h6>").append(text).append("</h6>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder i() {
        return open("i");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder i(String text) {
        html.append("<i>").append(text).append("</i>");
        return this;
    }

    /**
     * 构造
     *
     * @return Img
     */
    public Img img() {
        return new Img(this);
    }

    /**
     * 构造
     *
     * @param src 字符串
     * @return HtmlBuilder
     */
    public HtmlBuilder img(String src) {
        return img().src(src).close();
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder p() {
        return open("p");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder p(String text) {
        html.append("<p>").append(text).append("</p>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder small() {
        return open("small");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder small(String text) {
        html.append("<small>").append(text).append("</small>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder strike() {
        return open("strike");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder strike(String text) {
        html.append("<strike>").append(text).append("</strike>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder strong() {
        return open("strong");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder strong(String text) {
        html.append("<strong>").append(text).append("</strong>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder sub() {
        return open("sub");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder sub(String text) {
        html.append("<sub>").append(text).append("</sub>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder sup() {
        return open("sup");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder sup(String text) {
        html.append("<sup>").append(text).append("</sup>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder tt() {
        return open("tt");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder tt(String text) {
        html.append("<tt>").append(text).append("</tt>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder u() {
        return open("u");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder u(String text) {
        html.append("<u>").append(text).append("</u>");
        return this;
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder ul() {
        return open("ul");
    }

    /**
     * 构造
     *
     * @return HtmlBuilder
     */
    public HtmlBuilder li() {
        return open("li");
    }

    /**
     * 构造
     *
     * @param text 文本
     * @return HtmlBuilder
     */
    public HtmlBuilder li(String text) {
        html.append("<li>").append(text).append("</li>");
        return this;
    }

    /**
     * 返回字符串
     *
     * @return 字符串类型
     */
    public String build() {
        return html.toString();
    }

    @Override
    public String toString() {
        return html.toString();
    }

    public static class Tag {
        final HtmlBuilder builder;
        final String element;
        String separator = "";

        /**
         * 构造
         *
         * @param builder HtmlBuilder
         * @param element 字符串
         */
        public Tag(HtmlBuilder builder, String element) {
            this.builder = builder;
            this.element = element;
            open();
        }

        /**
         * 拼接
         */
        protected void open() {
            builder.append('<').append(element).append(' ');
        }

        /**
         * 结束
         *
         * @return 拼接
         */
        public HtmlBuilder close() {
            return builder.append("</").append(element).append('>');
        }

        @Override
        public String toString() {
            return builder.toString();
        }
    }

    public static class Font extends Tag {
        /**
         * 构造
         */
        public Font() {
            this(new HtmlBuilder());
        }

        /**
         * 构造
         *
         * @param builder HtmlBuilder
         */
        public Font(HtmlBuilder builder) {
            super(builder, "font");
        }

        /**
         * 构造
         *
         * @param size 字体大小
         * @return 字体大小
         */
        public Font size(int size) {
            builder.append(separator).append("size=\"").append(size).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param size 大小
         * @return 字体大小
         */
        public Font size(String size) {
            builder.append(separator).append("size=\"").append(size).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param color 颜色
         * @return 颜色
         */
        public Font color(int color) {
            return color(String.format(Locale.ROOT,"#%06X", 0xFFFFFF & color));
        }

        /**
         * 构造
         *
         * @param color 颜色
         * @return Font
         */
        public Font color(String color) {
            String rgb = fromStrToRGB(color);
            builder.append(separator).append("style=\"color:").append(rgb).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param face 字符串
         * @return Font
         */
        public Font face(String face) {
            builder.append(separator).append("face=\"").append(face).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param text 文本
         * @return Font
         */
        public Font text(String text) {
            builder.append('>').append(text);
            return this;
        }
    }

    public static class Img extends Tag {
        /**
         * 构造
         */
        public Img() {
            this(new HtmlBuilder());
        }

        /**
         * 构造
         *
         * @param builder HtmlBuilder
         */
        public Img(HtmlBuilder builder) {
            super(builder, "img");
        }

        /**
         * 构造
         *
         * @param src 字符串
         * @return Img
         */
        public Img src(String src) {
            builder.append(separator).append("src=\"").append(src).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param alt 字符串
         * @return Img
         */
        public Img alt(String alt) {
            builder.append(separator).append("alt=\"").append(alt).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param height 字符串高度
         * @return Img
         */
        public Img height(String height) {
            builder.append(separator).append("height=\"").append(height).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param height 高度
         * @return Img
         */
        public Img height(int height) {
            builder.append(separator).append("height=\"").append(height).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param width 宽度
         * @return Img
         */
        public Img width(String width) {
            builder.append(separator).append("width=\"").append(width).append('\"');
            separator = " ";
            return this;
        }

        /**
         * 构造
         *
         * @param width 宽度
         * @return Img
         */
        public Img width(int width) {
            builder.append(separator).append("width=\"").append(width).append('\"');
            separator = " ";
            return this;
        }

        @Override
        public HtmlBuilder close() {
            return builder.append('>');
        }
    }

    private static String fromStrToRGB(String str) {
        if (str == null || str.length() < 6) {
            return "";
        }
        int length = str.length();
        String str2 = str.substring(length - 6, length - 4);
        String str3 = str.substring(length - 4, length - 2);
        String str4 = str.substring(length - 2, str.length());

        int red = Integer.parseInt(str2, 16);
        int green = Integer.parseInt(str3, 16);
        int blue = Integer.parseInt(str4, 16);

        return "rgb(" + red + "," + green + "," + blue + ")";
    }

    /**
     * 转换成rgb
     *
     * @param color 颜色
     * @return 颜色值
     */
    public String fromStrToRGB(int color) {
        String str = String.format(Locale.ROOT,"#%06X", (0xFFFFFF & color));
        return fromStrToRGB(str);
    }
}
